#include "ispmaster.h"

/* Private variables ---------------------------------------------------------*/

/*This parameter must be configration depends on hardware connect by customer */
#define huartx (huart1)

#define ACK_MCU 0x79
#define A_NREST_STARTUART 2
#define TimeOUT_USART 5000
#define Erase_time_delay 30
#define bank2_mass_erase 0xFFFD
#define bank1_mass_erase 0xFFFE
#define GLOBAL_MASS_ERASE 0xFFFF
#define Read_UProtect_Commend 0x92
#define Read_Protect_Commend 0x82
#define Write_Uprotect_Commend 0x73
#define Write_Protect_Commend 0x63
#define Write_Memory 0x31
#define Go_Commend 0x31
#define Read_Memory 0x11
#define Get_ID_command 0x02
#define Get_Version_ReadProtection_Status 0x01
#define GET_Command 0x00
#define SYN_Frame 0x7F
#define NACK_MCU 0x1F
#define Run_Address 0x08000000
#define Code_Size 3216

#define Key_Pin GPIO_PIN_13
#define Key_GPIO_Port GPIOC
#define NREST_controler_Pin GPIO_PIN_0
#define NREST_controler_GPIO_Port GPIOA
#define BOOT0_Controler_Pin GPIO_PIN_1
#define BOOT0_Controler_GPIO_Port GPIOA
#define USART_TXD_for_programer_Pin GPIO_PIN_9
#define USART_TXD_for_programer_GPIO_Port GPIOA
#define USART_RXD_for_programer_Pin GPIO_PIN_10
#define USART_RXD_for_programer_GPIO_Port GPIOA

/* Private variables ---------------------------------------------------------*/
uint8_t version[10] = {0};
uint8_t PIDBuffer[10] = {0};
uint8_t MemoryBuffer[255] = {0};
uint8_t Cur_Commend_list[20] = {0};
uint8_t Cru_status = 0;
uint8_t E_Erase_Commend = 0x43;
/*set whether need debug status,1 means in debug status; 0 means relase status*/
uint8_t debug_info = 0; //


void Reset_AND_Entor_Run_Mode(void);
void Reset_AND_Entor_ISP_Mode(void);
MCU_Status SYN_TARGET_MCU(void);
void Get_Version_ReadProtection_Status_function(uint8_t *Version);
void Wait_onetime_key_event(void);
void USART_send_commend(uint8_t temp, uint8_t Size);
uint8_t USART_receive_ACK(void);
void Get_ID_command_Function(uint8_t *PID);
MCU_Status Read_Memory_Function(uint8_t *Buffer, uint32_t Address, uint8_t size);
MCU_Status GET_Command_function(uint8_t *Commend_list, uint8_t *Versiontemp);
MCU_Status E_Erase_Commend_function(uint32_t Address, uint8_t Spec_add_Flag, uint8_t Page);
MCU_Status Write_Memory_Function(uint32_t *writebuffer, uint32_t size, uint32_t Address);
MCU_Status Go_Commend_Function(uint32_t T_Address);
MCU_Status Write_Protect_Commend_Function(uint8_t *sector_list, uint8_t size);
MCU_Status Write_Uprotect_Commend_Function(void);
MCU_Status Read_Protect_Commend_Function(void);


int isp(ispm_t *p)
{
    uint32_t *pp;
    pp = (uint32_t *)p->srcaddr;

    /*Control target MCU entor ISP mode*/
    Reset_AND_Entor_ISP_Mode();

    /*Synchronous Target MCU*/
    while (SYN_TARGET_MCU() != Ready)
    {
        HAL_Delay(1000);
        /*Control target MCU entor ISP mode*/
        Reset_AND_Entor_ISP_Mode();
    }

    /*just for test*/
    // Get_Version_ReadProtection_Status_function(version);
    // Get_ID_command_Function(PIDBuffer);

    // this function can be uesed in check the programe context whether right
    // Read_Memory_Function(MemoryBuffer,Run_Address,255);
    GET_Command_function(Cur_Commend_list, &version[0]);

    E_Erase_Commend_function(GLOBAL_MASS_ERASE, 1, 0);
    HAL_Delay(Erase_time_delay);

    Write_Memory_Function(pp, Code_Size, Run_Address);
    Go_Commend_Function(Run_Address);
    Reset_AND_Entor_Run_Mode();
}

void Reset_AND_Entor_Run_Mode(ispm_t *p)
{
    /*set BOOT to low voltage*/
    p->ctrlrst(0);
    p->ctrlboot0(0);
    p->delaynms(1);
    p->ctrlrst(1);
}

/*reset Target MCU and let it entor ISP mode*/
void Reset_AND_Entor_ISP_Mode(ispm_t *p)
{
    /*set NRST_Pin to Low voltage*/
    p->ctrlrst(0);
    /*set BOOT0_Pin to High voltage*/
    p->ctrlboot0(1);
    p->delaynms(1);

    /*set NRST_Pin to high voltage*/
    p->ctrlrst(1);
    /*this delay function can delete if Line captor is enough small, but recommend add for safe*/
    p->delaynms(1);
    /*set BOOT0_Pin to Low voltage, because this Low voltage is need run the APP*/
    p->ctrlboot0(0);

    p->delaynms(A_NREST_STARTUART); // the 'A_NREST_STARTUART' value must depends on AN2606
}


/*send the commend by USART*/
void USART_send_commend(uint8_t temp, uint8_t Size)
{

    while (HAL_UART_Transmit(&huartx, &temp, Size, TimeOUT_USART) != HAL_OK)
    {
    }
}
/*Receive data from USART*/
uint8_t USART_receive_ACK(void)
{
    uint8_t temp;
    while (HAL_UART_Receive(&huartx, &temp, 1, TimeOUT_USART) != HAL_OK)
    {
    }
    return temp;
}

/*this function is must becalled befor another commend is called*/
MCU_Status SYN_TARGET_MCU(void)
{

    uint8_t temp = NACK_MCU;

    USART_send_commend(SYN_Frame, 1);
    temp = USART_receive_ACK();

    switch (temp)
    {
    case ACK_MCU:
        Cru_status |= 1 << 7; // set status
        break;
    case NACK_MCU:
        Cru_status &= ~(1 << 7);

        // NVIC_SystemReset();
        break;

    default:
        break;
    }

    if (0x00 == (Cru_status & 0x80))
    {
        return Error;
    }
    else
    {
        return Ready;
    }
}


void Get_ID_command_Function(uint8_t *PID)
{

    uint8_t Number = 0, temp[2];
    temp[0] = Get_ID_command;
    temp[1] = 0xFF - Get_ID_command;
    while (HAL_UART_Transmit(&huartx, temp, 2, TimeOUT_USART) != HAL_OK)
    {
    }
    while (HAL_UART_Receive(&huartx, &temp[0], 1, TimeOUT_USART) != HAL_OK)
    {
    }
    switch (temp[0])
    {
    case ACK_MCU:
    {
        while (HAL_UART_Receive(&huartx, &Number, 1, TimeOUT_USART) != HAL_OK)
        {
        }
        // for(i=0;i<Number+1;i++)
        while (HAL_UART_Receive(&huartx, PID, Number + 1, TimeOUT_USART) != HAL_OK)
        {
        }
        while (HAL_UART_Receive(&huartx, temp, 1, TimeOUT_USART) != HAL_OK)
        {
        }
        if (temp[0] == ACK_MCU)
        {
        }
        else
        {
        }
    }
    break;
    case NACK_MCU:

        break;
    default:
        break;
    }
}

// read the version and readoutprotection status
void Get_Version_ReadProtection_Status_function(uint8_t *Version)
{

    uint8_t temp[2] = {0, 0};

    temp[0] = Get_Version_ReadProtection_Status;
    temp[1] = 0xFF - Get_Version_ReadProtection_Status;
    while (HAL_UART_Transmit(&huartx, temp, 2, TimeOUT_USART) != HAL_OK)
    {
    }
    while (HAL_UART_Receive(&huartx, temp, 1, TimeOUT_USART) != HAL_OK)
    {
    }

    switch (temp[0])
    {
    case ACK_MCU:
    {
        while (HAL_UART_Receive(&huartx, Version, 3, TimeOUT_USART) != HAL_OK)
        {
        }
        while (HAL_UART_Receive(&huartx, temp, 1, TimeOUT_USART) != HAL_OK)
        {
        }
#if debug_info
        if (temp[0] == ACK_MCU)
        {
        }
        else
        {
        }
#endif
    }
    break;
    case NACK_MCU:

        break;
    default:
        break;
    }
}

MCU_Status Read_Memory_Function(uint8_t *Buffer, uint32_t Address, uint8_t size)
{

    uint8_t temp[2] = {0, 0};
    uint8_t address[4], checksum_temp, complement_size;
    size = size - 1;

    complement_size = 0xff - size;

    address[0] = (uint8_t)(Address >> 24);
    address[1] = (uint8_t)(Address >> 16);
    address[2] = (uint8_t)(Address >> 8);
    address[3] = (uint8_t)(Address >> 0);
    checksum_temp = address[0] ^ address[1] ^ address[2] ^ address[3];

    temp[0] = Read_Memory;
    temp[1] = 0xFF - Read_Memory;
    while (HAL_UART_Transmit(&huartx, temp, 2, TimeOUT_USART) != HAL_OK)
    {
    }
    while (HAL_UART_Receive(&huartx, temp, 1, TimeOUT_USART) != HAL_OK)
    {
    }

    switch (temp[0])
    {
    case ACK_MCU:
    {
        while (HAL_UART_Transmit(&huartx, address, 4, TimeOUT_USART) != HAL_OK)
        {
        } // send address
        while (HAL_UART_Transmit(&huartx, &checksum_temp, 1, TimeOUT_USART) != HAL_OK)
        {
        }
        while (HAL_UART_Receive(&huartx, temp, 1, TimeOUT_USART) != HAL_OK)
        {
        }
        if (temp[0] == ACK_MCU)
        {

            while (HAL_UART_Transmit(&huartx, &size, 1, TimeOUT_USART) != HAL_OK)
            {
            }
            while (HAL_UART_Transmit(&huartx, &complement_size, 1, TimeOUT_USART) != HAL_OK)
            {
            }

            while (HAL_UART_Receive(&huartx, temp, 1, TimeOUT_USART) != HAL_OK)
            {
            }
            if (temp[0] == ACK_MCU)
            {
                while (HAL_UART_Receive(&huartx, Buffer, size + 1, TimeOUT_USART) != HAL_OK)
                {
                }
            }
            else
            {
                return Error;
            }
        }
        else
        {

            return Error;
        }
    }
    break;
    case NACK_MCU:

        break;
    default:
        break;
    }

    return Ready;
}
/*get Commend*/
MCU_Status GET_Command_function(uint8_t *Commend_list, uint8_t *Versiontemp)
{

    uint8_t temp[2] = {0, 0};
    temp[0] = GET_Command;
    temp[1] = 0xFF - GET_Command;
    while (HAL_UART_Transmit(&huartx, temp, 2, TimeOUT_USART) != HAL_OK)
    {
    }
    while (HAL_UART_Receive(&huartx, temp, 1, TimeOUT_USART) != HAL_OK)
    {
    }

    switch (temp[0])
    {
    case ACK_MCU:
    {
        while (HAL_UART_Receive(&huartx, temp, 1, TimeOUT_USART) != HAL_OK)
        {
        } // temp means the Number
        while (HAL_UART_Receive(&huartx, Versiontemp, 1, TimeOUT_USART) != HAL_OK)
        {
        } // temp means the Number
        while (HAL_UART_Receive(&huartx, Commend_list, temp[0], TimeOUT_USART) != HAL_OK)
        {
        }                                  // get the list
        E_Erase_Commend = Commend_list[6]; // detail information please reference AN3155
        while (HAL_UART_Receive(&huartx, temp, 1, TimeOUT_USART) != HAL_OK)
        {
        }
        if (temp[0] == ACK_MCU)
            return Ready;
        else
        {
        }
    }
    break;
    case NACK_MCU:
        //*this place customer can add some code for NACK processing*//
        /*

        */
        break;
    default:
        break;
    }

    return Error;
}

MCU_Status Write_Memory_Function(uint32_t *writebuffer, uint32_t size, uint32_t T_Address)
{

    uint8_t temp[2] = {0, 0};
    uint8_t address[4], checksum_temp, itemp;
    uint8_t *tempp = (uint8_t *)writebuffer;
    uint32_t Address = T_Address;

    while (size != 0)
    {
        address[0] = (uint8_t)(Address >> 24);
        address[1] = (uint8_t)(Address >> 16);
        address[2] = (uint8_t)(Address >> 8);
        address[3] = (uint8_t)(Address >> 0);
        checksum_temp = address[0] ^ address[1] ^ address[2] ^ address[3];

        temp[0] = Write_Memory;
        temp[1] = 0xFF - Write_Memory;
        while (HAL_UART_Transmit(&huartx, temp, 2, TimeOUT_USART) != HAL_OK)
        {
        }
        while (HAL_UART_Receive(&huartx, temp, 1, TimeOUT_USART) != HAL_OK)
        {
        }

        switch (temp[0])
        {
        case ACK_MCU:
            /*send four byte address*/
            while (HAL_UART_Transmit(&huartx, address, 4, TimeOUT_USART) != HAL_OK)
            {
            }
            /*send the address checksum*/
            while (HAL_UART_Transmit(&huartx, &checksum_temp, 1, TimeOUT_USART) != HAL_OK)
            {
            }

            /*received the feedback from Target MCU*/
            while (HAL_UART_Receive(&huartx, temp, 1, TimeOUT_USART) != HAL_OK)
            {
            }

            /*feedback is right*/
            if (temp[0] == ACK_MCU)
            {

                if (size >= 256)
                { // when data is bigger than 255
                    temp[0] = 255;
                    /*send the number-1 of program*/
                    while (HAL_UART_Transmit(&huartx, temp, 1, TimeOUT_USART) != HAL_OK)
                    {
                    }
                    /*send the data to bootloader*/
                    while (HAL_UART_Transmit(&huartx, tempp, 256, TimeOUT_USART) != HAL_OK)
                    {
                    }
                    /*clear checksum*/
                    checksum_temp = 255;
                    for (itemp = 0; itemp < 128; itemp++)
                    {
                        checksum_temp ^= tempp[itemp * 2] ^ tempp[itemp * 2 + 1];
                    }
                    /*send the checksum Byte*/
                    while (HAL_UART_Transmit(&huartx, &checksum_temp, 1, TimeOUT_USART) != HAL_OK)
                    {
                    }
                    tempp = tempp + 256;
                    size = size - 256;
                    Address += 256;
                    /*received the feedback from Target MCU*/
                    while (HAL_UART_Receive(&huartx, temp, 1, TimeOUT_USART) != HAL_OK)
                    {
                    }
                    if (temp[0] == ACK_MCU)
                    {
                    }
                    else
                    {
                    }
                }
                else
                { // reserve data is not enogh 256 bytes
                    temp[0] = size - 1;
                    /*send the number-1 of program*/
                    while (HAL_UART_Transmit(&huartx, temp, 1, TimeOUT_USART) != HAL_OK)
                    {
                    }
                    /*send the data to bootloader*/
                    while (HAL_UART_Transmit(&huartx, tempp, size, TimeOUT_USART) != HAL_OK)
                    {
                    }
                    /*clear checksum*/
                    checksum_temp = size - 1;
                    for (itemp = 0; itemp < (size / 2); itemp++)
                    {
                        checksum_temp ^= tempp[itemp * 2] ^ tempp[itemp * 2 + 1];
                    } /*if the size is odd mumber*/
                    if (size % 2 == 1)
                    {
                        checksum_temp ^= tempp[size - 1];
                    }
                    /*send the checksum Byte*/
                    while (HAL_UART_Transmit(&huartx, &checksum_temp, 1, TimeOUT_USART) != HAL_OK)
                    {
                    }
                    // tempp=tempp+256;
                    while (HAL_UART_Receive(&huartx, temp, 1, TimeOUT_USART) != HAL_OK)
                    {
                    }
                    if (temp[0] == ACK_MCU)
                    {
                    }
                    else
                    {
                    }
                    size = 0;
                }
            }

            break;
        case NACK_MCU:
            //*this place customer can add some code for NACK processing*//
            /*

            */
            break;
        default:
            break;
        }
    }
    return Error;
}

MCU_Status Go_Commend_Function(uint32_t T_Address)
{

    uint8_t temp[2] = {0, 0};
    uint8_t address[4], checksum_temp;
    uint32_t Address = T_Address;

    address[0] = (uint8_t)(Address >> 24);
    address[1] = (uint8_t)(Address >> 16);
    address[2] = (uint8_t)(Address >> 8);
    address[3] = (uint8_t)(Address >> 0);
    checksum_temp = address[0] ^ address[1] ^ address[2] ^ address[3];

    temp[0] = Go_Commend;
    temp[1] = 0xFF - Go_Commend;
    while (HAL_UART_Transmit(&huartx, temp, 2, TimeOUT_USART) != HAL_OK)
    {
    }
    while (HAL_UART_Receive(&huartx, temp, 1, TimeOUT_USART) != HAL_OK)
    {
    }
    switch (temp[0])
    {
    case ACK_MCU:
        while (HAL_UART_Transmit(&huartx, address, 4, TimeOUT_USART) != HAL_OK)
        {
        }
        while (HAL_UART_Transmit(&huartx, &checksum_temp, 1, TimeOUT_USART) != HAL_OK)
        {
        }
        while (HAL_UART_Receive(&huartx, temp, 1, TimeOUT_USART) != HAL_OK)
        {
        }
        if (temp[0] == ACK_MCU)
        { /*this place can add customer's callback*/
            Reset_AND_Entor_Run_Mode();
            return Ready;
        }
        else
        {
            /*this place can add customer's Error callback*/
        }
        break;
    case NACK_MCU:
        //*this place customer can add some code for NACK processing*//
        /*

        */
        break;
    default:
        break;
    }

    return Ready;
}

/*this commend is upprotect all sectors in flash*/
MCU_Status Write_Uprotect_Commend_Function(void)
{

    uint8_t temp[2] = {0, 0};

    temp[0] = Write_Uprotect_Commend;
    temp[1] = 0xFF - Write_Uprotect_Commend;
    while (HAL_UART_Transmit(&huartx, temp, 2, TimeOUT_USART) != HAL_OK)
    {
    }
    while (HAL_UART_Receive(&huartx, temp, 1, TimeOUT_USART) != HAL_OK)
    {
    }

    switch (temp[0])
    {
    case ACK_MCU:
        while (HAL_UART_Receive(&huartx, temp, 1, TimeOUT_USART) != HAL_OK)
        {
        }
        if (temp[0] == ACK_MCU)
        {
            return Ready;
        }
        else
        {
        }
        break;
    case NACK_MCU:
        //*this place customer can add some code for NACK processing*//
        /*

        */
        break;
    default:
        break;
    }
    return Error;
}
/*Write Protect commend*/
MCU_Status Write_Protect_Commend_Function(uint8_t *sector_list, uint8_t size)
{

    uint8_t temp[2] = {0, 0}, checksum_temp = 0, send_size, itemp;
    send_size = size - 1;

    temp[0] = Write_Protect_Commend;
    temp[1] = 0xFF - Write_Protect_Commend;
    while (HAL_UART_Transmit(&huartx, temp, 2, TimeOUT_USART) != HAL_OK)
    {
    }
    while (HAL_UART_Receive(&huartx, temp, 1, TimeOUT_USART) != HAL_OK)
    {
    }

    for (itemp = 0; itemp < size / 2; itemp++)
    {
        checksum_temp ^= sector_list[itemp * 2] ^ sector_list[itemp * 2 + 1];
    }

    switch (temp[0])
    {

    case ACK_MCU:
        /*send the number of need protect sectors*/
        while (HAL_UART_Transmit(&huartx, &send_size, 1, TimeOUT_USART) != HAL_OK)
        {
        }
        /*send the list of sectors*/
        while (HAL_UART_Transmit(&huartx, sector_list, size, TimeOUT_USART) != HAL_OK)
        {
        }
        /*send the checksum*/
        while (HAL_UART_Transmit(&huartx, &checksum_temp, 1, TimeOUT_USART) != HAL_OK)
        {
        }

        /*wait the feedback from Target MCU*/
        while (HAL_UART_Receive(&huartx, temp, 1, TimeOUT_USART) != HAL_OK)
        {
        }
        if (temp[0] == ACK_MCU)
        {
            return Ready;
        }

        break;
    case NACK_MCU:
        //*this place customer can add some code for NACK processing*//
        /*

        */
        break;
    default:
        break;
    }

    return Error;
}

MCU_Status Read_Protect_Commend_Function(void)
{

    uint8_t temp[2] = {0, 0};

    temp[0] = Read_Protect_Commend;
    temp[1] = 0xFF - Read_Protect_Commend;
    while (HAL_UART_Transmit(&huartx, temp, 2, TimeOUT_USART) != HAL_OK)
    {
    }
    while (HAL_UART_Receive(&huartx, temp, 1, TimeOUT_USART) != HAL_OK)
    {
    }

    switch (temp[0])
    {
    case ACK_MCU:
        while (HAL_UART_Receive(&huartx, temp, 1, TimeOUT_USART) != HAL_OK)
        {
        }
        if (temp[0] == ACK_MCU)
        {
            return Ready;
        }
        else
        {
        }
        break;
    case NACK_MCU:
        //*this place customer can add some code for NACK processing*//
        /*

        */
        break;
    default:
        break;
    }
    return Error;
}

MCU_Status Read_UProtect_Commend_Function(void)
{

    uint8_t temp[2] = {0, 0};

    temp[0] = Read_UProtect_Commend;
    temp[1] = 0xFF - Read_UProtect_Commend;
    while (HAL_UART_Transmit(&huartx, temp, 2, TimeOUT_USART) != HAL_OK)
    {
    }
    while (HAL_UART_Receive(&huartx, temp, 1, TimeOUT_USART) != HAL_OK)
    {
    }

    switch (temp[0])
    {
    case ACK_MCU:
        while (HAL_UART_Receive(&huartx, temp, 1, TimeOUT_USART) != HAL_OK)
        {
        }
        if (temp[0] == ACK_MCU)
        {
            return Ready;
        }
        else
        {
        }
        break;
    case NACK_MCU:
        //*this place customer can add some code for NACK processing*//
        /*

        */
        break;
    default:
        break;
    }
    return Error;
}

/*This commend is must call after GET_Command_function be call*/
MCU_Status E_Erase_Commend_function(uint32_t Address, uint8_t Spec_add_Flag, uint8_t Page)
{

    uint8_t temp[2] = {0, 0}, checksum;

    temp[0] = E_Erase_Commend;
    temp[1] = 0xFF - E_Erase_Commend;
    while (HAL_UART_Transmit(&huartx, temp, 2, TimeOUT_USART) != HAL_OK)
    {
    }
    while (HAL_UART_Receive(&huartx, temp, 1, TimeOUT_USART) != HAL_OK)
    {
    }

    switch (temp[0])
    {
    case ACK_MCU:
    {
        if (Spec_add_Flag == 0x01)
        {

            switch (Address)
            {
            case GLOBAL_MASS_ERASE:
            {
                temp[0] = 0xFF;
                temp[1] = 0xFF;
                checksum = temp[0] ^ temp[1];
                while (HAL_UART_Transmit(&huartx, temp, 2, TimeOUT_USART) != HAL_OK)
                {
                }
                while (HAL_UART_Transmit(&huartx, &checksum, 1, TimeOUT_USART) != HAL_OK)
                {
                }
                while (HAL_UART_Receive(&huartx, temp, 1, TimeOUT_USART) != HAL_OK)
                {
                }
                if (temp[0] == ACK_MCU)
                {
                    return Ready;
                }
            }

            break;
            case bank1_mass_erase:
            {
                temp[0] = 0xFF;
                temp[1] = 0xFE;
                checksum = temp[0] ^ temp[1];
                while (HAL_UART_Transmit(&huartx, temp, 2, TimeOUT_USART) != HAL_OK)
                {
                }
                while (HAL_UART_Transmit(&huartx, &checksum, 1, TimeOUT_USART) != HAL_OK)
                {
                }
                while (HAL_UART_Receive(&huartx, temp, 1, TimeOUT_USART) != HAL_OK)
                {
                }
                if (temp[0] == ACK_MCU)
                {
                    return Ready;
                }
            }
            break;
            case bank2_mass_erase:
            {
                temp[0] = 0xFF;
                temp[1] = 0xFD;
                checksum = temp[0] ^ temp[1];
                while (HAL_UART_Transmit(&huartx, temp, 2, TimeOUT_USART) != HAL_OK)
                {
                }
                while (HAL_UART_Transmit(&huartx, &checksum, 1, TimeOUT_USART) != HAL_OK)
                {
                }
                while (HAL_UART_Receive(&huartx, temp, 1, TimeOUT_USART) != HAL_OK)
                {
                }
                if (temp[0] == ACK_MCU)
                {
                    return Ready;
                }
            }
            break;
            default:
                break;
            }
        }
    }
    break;
    case NACK_MCU:
        //*this place customer can add some code for NACK processing*//
        /*

        */
        break;
    default:
        break;
    }
    return Error;
}

